package cn.sh.library.mgts.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;

import cn.sh.library.mgts.bean.InstanceSearchBean;
import cn.sh.library.mgts.utils.IPUtils;
import cn.sh.library.mgts.utils.StringUtilC;

public class MergeParts {

	// 高级检索
	static final Map<String, String> EXPR_FIELD_MAP = new HashMap<String, String>() {
		{
			// 高级检索
			put("TM", "title.label.@value");// 题名
			put("CS", "seriesLabel");// 从事
			put("SSH", "item.shelfMark");// 索书号
			put("ZRZ", "contribution.personName.@value");// 责任者
			put("CBD", "provisionActivity.proPlace.@value");// 出版地
			put("CBJG", "provisionActivity.proOrganization.@value");// 出版机构
			put("YEAR", "provisionActivity.proDate");// 出版年
			put("ZTC", "complexSubject.labelConcat");// 主题词
			put("FXJG", "publication.pubOrganization.@value");// 出版发行机构
			put("ALL", "all");// 全字段

			// 分类
			put("FL", "classification.level");
			// 分面 出版年 出版社 出版地 责任者 分类 关键词(work下主题词)
			put("FACET_YEAR", "provisionActivity.proDate");
			put("FACET_PUBLISHER", "provisionActivity.proOrganization.@value");
			put("FACET_PLACE", "provisionActivity.proPlace.@value");
			put("FACET_PERSON", "contribution.personName.@value");
			put("FACET_CLASSES", "classfacet");
			put("FACET_SUBJECT", "complexSubject.labelConcat");
			put("FACET_ACCESSLEVEL", "item.accessLevel");

			// workDetail
			put("WORK", "workUri.@id");

			// 地图检索
			put("LONG", "long");
			put("LAT", "lat");
		}
	};
	

	// 高级检索
	static final Map<String, String> SORT_FIELD_MAP = new HashMap<String, String>() {
		{
			// 高级检索
			put("person", "contribution.personNamePny.@value.keyword");// 责任者
			put("title", "title.labelPny.@value.keyword");// 题名
			put("score", "_score");// score
		}
	};
	
	// 地图检索--地名获取
	public static SearchSourceBuilder mapSearch(InstanceSearchBean mgtsInstanceSearchBean, String points) {
		SearchSourceBuilder builder = new SearchSourceBuilder();
		BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();

		// location检索
		if (StringUtils.isNotEmpty(points)) {
			List<GeoPoint> geoPoints = new ArrayList<>();
			String regularPoints = points.substring(9, points.length() - 2);
			String[] pointsArray = regularPoints.split(",");
			for (String point : pointsArray) {
				String[] longAndlat = point.split(" ");
				geoPoints.add(new GeoPoint(Double.parseDouble(longAndlat[1]), Double.parseDouble(longAndlat[0])));
			}
			// 测试多值使用
//			boolBuilder.should(QueryBuilders.termQuery("place.uri.keyword", "http://data.library.sh.cn/entity/place/hfpkaw7jcecxunhu"));
			//geoPoints 不为空才走地图检索
			if(!StringUtilC.isEmpty(geoPoints)) {
				boolBuilder.must().add(QueryBuilders.geoPolygonQuery("provisionActivity.place.location", geoPoints));
			}
		}

		// 简单检索 二次检索 高级检索之全字段检索
		searchCdtn(boolBuilder, mgtsInstanceSearchBean.getCdtn());
		freetextCdtn(boolBuilder, mgtsInstanceSearchBean.getFreetext());
		builder.query(boolBuilder);
		
		return builder;
	}

	// 地图检索--过滤
	public static boolean mapSearchFilter(String longs, String lat,String points) {
		
		double longD = Double.parseDouble(longs);
		double latD = Double.parseDouble(lat);

		// 地图检索--过滤
		double maxlong = 0,minlong = 360,maxlat = 0,minlat=360;
		if (StringUtils.isNotEmpty(points)) {
			String regularPoints = points.substring(9, points.length() - 2);
			String[] pointsArray = regularPoints.split(",");
			for (String point : pointsArray) {
				String[] longAndlat = point.split(" ");
				if(Double.parseDouble(longAndlat[1])>maxlat) {
					maxlat = Double.parseDouble(longAndlat[1]);
				}
				if(Double.parseDouble(longAndlat[1])<minlat) {
					minlat = Double.parseDouble(longAndlat[1]);
				}
				if(Double.parseDouble(longAndlat[0])>maxlong) {
					maxlong = Double.parseDouble(longAndlat[0]);
				}
				if(Double.parseDouble(longAndlat[0])<minlong) {
					minlong = Double.parseDouble(longAndlat[0]);
				}
			}
		}
		if(longD>minlong&&longD<maxlong&&latD>minlat&&latD<maxlat) {
			return true;
		}else {
			return false;
		}
		
	}

	// 地图检索2--获取instance'
	public static SearchSourceBuilder instanceSearchWithPlace(String placeUri, String freetext, String startYear, String endYear) {
		SearchSourceBuilder builder = new SearchSourceBuilder();
		BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
		// 简单检索
		freetextCdtn(boolBuilder, freetext);
		// 地名uri检索

		if (StringUtils.isNotEmpty(placeUri)) {
			String[] placeUriArr = placeUri.split(",");
			BoolQueryBuilder boolBuilderNew = QueryBuilders.boolQuery();
			for (String uri : placeUriArr) {
				boolBuilderNew.should(QueryBuilders.termQuery("provisionActivity.place.uri.keyword", uri));
			}
			boolBuilder.must().add(boolBuilderNew);
		}

		if(StringUtils.isNotBlank(startYear)) {
			boolBuilder.must(QueryBuilders.rangeQuery(EXPR_FIELD_MAP.get("YEAR") + ".keyword").gte(startYear));
		}
		
		if(StringUtils.isNotBlank(endYear)) {
			boolBuilder.must(QueryBuilders.rangeQuery(EXPR_FIELD_MAP.get("YEAR") + ".keyword").lte(endYear));
		}
		
		if(!IPUtils.isPrivateIP()) {
			boolBuilder.mustNot(QueryBuilders.matchQuery("isNew.keyword", "guotulib"));
		}
		
		builder.query(boolBuilder);

		return builder;
	}

	public static void searchCdtn(BoolQueryBuilder boolBuilder, List<Map<String, String>> cdtns) {
		if(boolBuilder == null) {
			boolBuilder = QueryBuilders.boolQuery();
		}
		if (cdtns != null && cdtns.size() > 0) {
			// 其他
//			String fieldtext = "";
			for (Map<String, String> cdtn : cdtns) {
				if (StringUtils.isNotEmpty(EXPR_FIELD_MAP.get(cdtn.get("field")))
						&& StringUtils.isNotEmpty(cdtn.get("value"))) {
					if ("ALL".equals(cdtn.get("field"))) {
						freetextCdtn(boolBuilder, cdtn.get("value"));
					} else {
						String logic = StringUtils.isEmpty(cdtn.get("logic")) ? "and"
								: cdtn.get("logic").trim().toLowerCase();// "and"
						String field = EXPR_FIELD_MAP.get(cdtn.get("field"));// provisionActivity.proDate
						// 如果value包含空格 需要将值拆分，每个值做检索
						if (cdtn.get("value").trim().indexOf(" ") != -1
								&& !(cdtn.get("field").equals("FACET_CLASSES"))) {
							List<String> keywords = Arrays.asList(cdtn.get("value").trim().split(" "));
							
							for (String value : keywords) {
								if("：：=".indexOf(value) != -1) {
									continue;
								}
								switch (logic) {
								case "and":
									boolBuilder.must(queryCdtn(field, value, cdtn.get("type")));
									break;
								case "or":
									boolBuilder.should(queryCdtn(field, value, cdtn.get("type")));
									break;
								case "not":
									boolBuilder.mustNot(queryCdtn(field, value, cdtn.get("type")));
									break;

								default:
									break;
								}
							}
						} else {
							switch (logic) {
							case "and":
								boolBuilder.must(queryCdtn(field, cdtn.get("value").trim(), cdtn.get("type")));
								break;
							case "or":
								boolBuilder.should(queryCdtn(field, cdtn.get("value").trim(), cdtn.get("type")));
								break;
							case "not":
								boolBuilder.mustNot(queryCdtn(field, cdtn.get("value").trim(), cdtn.get("type")));
								break;

							default:
								break;
							}
						}
					}
				}
			}
		}
	}
	
	public static void freetextCdtn(BoolQueryBuilder boolBuilder, String freetext) {
		if(boolBuilder == null) {
			boolBuilder = QueryBuilders.boolQuery();
		}
		
		if (StringUtils.isNotBlank(freetext)) {
			// 检索值拼接 包含简单检索与二次检索参数
			List<String> keywords = Arrays.asList(freetext.trim().split(" "));
			for (String free : keywords) {
				if(StringUtils.isEmpty(free)) {
					continue;
				}
				boolBuilder.must().add(QueryBuilders.boolQuery()
						.should(QueryBuilders.matchPhraseQuery("title.label.@value", free)) // 题名
						.should(QueryBuilders.matchPhraseQuery("contribution.personName.@value", free)) // 著者
						.should(QueryBuilders.matchPhraseQuery("provisionActivity.proPlace.@value", free))// 出版地
						.should(QueryBuilders.matchPhraseQuery("provisionActivity.proOrganization.@value", free))// 出版社
						.should(QueryBuilders.matchPhraseQuery("provisionActivity.proDate", free))// 出版年
						.should(QueryBuilders.matchPhraseQuery("seriesLabel", free)) // 丛书
						.should(QueryBuilders.matchPhraseQuery("item.shelfMark", free))
						.should(QueryBuilders.matchPhraseQuery("complexSubject.authoritativeLabel", free))); // 索书号
			}
		}
	}
	
	// 高级检索
	public static SearchSourceBuilder instanceSearch(InstanceSearchBean mgtsInstanceSearchBean) {
		SearchSourceBuilder builder = new SearchSourceBuilder();
		BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
		searchCdtn(boolBuilder, mgtsInstanceSearchBean.getCdtn());

		if(!IPUtils.isPrivateIP()) {
			boolBuilder.mustNot(QueryBuilders.matchQuery("isNew.keyword", "guotulib"));
		}
		
		// 简单检索 二次检索 高级检索之全字段检索
		if (StringUtils.isNotEmpty(mgtsInstanceSearchBean.getFreetext())
				|| StringUtils.isNotEmpty(mgtsInstanceSearchBean.getSecondCdtn())) {
			// 检索值拼接 包含简单检索与二次检索参数
			String newText = mgtsInstanceSearchBean.getFreetext().trim() + " "
					+ mgtsInstanceSearchBean.getSecondCdtn().trim();
			freetextCdtn(boolBuilder, newText);
		}
		// 排序

		if (mgtsInstanceSearchBean.getSorts() != null && mgtsInstanceSearchBean.getSorts().size() > 0) {
			SortOrder order = SortOrder.DESC;
			String field = mgtsInstanceSearchBean.getSorts().get("field");
			if("0".equals(mgtsInstanceSearchBean.getSorts().get("type"))) {
				order = SortOrder.ASC;
			}else if ("1".equals(mgtsInstanceSearchBean.getSorts().get("type"))){
				order = SortOrder.DESC;
			}
			if(SORT_FIELD_MAP.containsKey(mgtsInstanceSearchBean.getSorts().get("field"))) {
				builder.sort(new FieldSortBuilder(SORT_FIELD_MAP.get(field)).order(order));
			}
		}

		builder.query(boolBuilder);
		return builder;
	}

	static QueryBuilder queryCdtn(String field, String value, String type) {// provisionActivity.proDate 1941 1
		QueryBuilder q = QueryBuilders.matchAllQuery();

		switch (type) {
		case "0":
			q = QueryBuilders.matchPhraseQuery(field,QueryParser.escape(value));
			break;

		case "1":
			q = QueryBuilders.matchPhraseQuery(field + ".keyword", value);
			break;

		case "2":
			q = QueryBuilders.rangeQuery(field + ".keyword").from(value);
			break;

		case "3":
			q = QueryBuilders.rangeQuery(field + ".keyword").to(value);
			break;

		case "4":
			q = QueryBuilders.existsQuery(field + ".keyword");
			break;

		case "5":
			q = QueryBuilders.prefixQuery(field, value);

		default:
			break;
		}

		return q;
	}

	// 详情页
	public static SearchSourceBuilder instanceDetailSearch(String instanceDetail) {
		SearchSourceBuilder builder = new SearchSourceBuilder();
		BoolQueryBuilder boolBuilder = new BoolQueryBuilder();
		builder.query(QueryBuilders.boolQuery().should(QueryBuilders.matchAllQuery()));
		// instance work detail
		if (!StringUtils.isEmpty(instanceDetail)) {
			boolBuilder.must().add(
					QueryBuilders.boolQuery().should(QueryBuilders.matchPhraseQuery("@id.keyword", instanceDetail)));
		}
		builder.query(boolBuilder);
		return builder;
	}

	public static SearchSourceBuilder workDetailSearch(InstanceSearchBean mgtsInstanceSearchBean) {
		SearchSourceBuilder builder = new SearchSourceBuilder();
		BoolQueryBuilder boolBuilder = new BoolQueryBuilder();

		searchCdtn(boolBuilder, mgtsInstanceSearchBean.getCdtn());
		builder.query(boolBuilder);
		return builder;
	}
	

	// test
	public static void main(String[] args) {

	}
}
